//-----------------------------------------------------------------------------
// FlatFour - FileSystem.cs
//
// A virtual file system manager.
//
// Written by Jason Perkins (jason@379.com)
// (C) 2001-2003 by 379, Inc.
// Source code licensed under the L-GPL, see LICENSE.txt for details.
//
// $Id: FileSystem.cs,v 1.3 2003/07/15 21:42:25 jason379 Exp $
//-----------------------------------------------------------------------------

using System;
using System.Collections;
using System.IO;
using System.Text;

namespace FlatFour
{
	public class FileSystem
	{
		private static Stack directoryStack;
		private static Hashtable mounts;

		//-----------------------------------------------------------------------------

		static FileSystem()
		{
			directoryStack = new Stack();
			directoryStack.Push(Directory.GetCurrentDirectory());

			mounts = new Hashtable();
		}

		//-----------------------------------------------------------------------------

		public static string MakeAbsolutePath(string path)
		{
			if (path.StartsWith("/")) return path;
			return Path.GetFullPath(path);
		}

		public static string MakeRelativePath(string root, string path)
		{
			// Prepare both paths for comparing
			root = MakeAbsolutePath(root);
			path = MakeAbsolutePath(path);

			char[] separator = new char[]{ Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
			string[] rootParts = root.Split(separator);
			string[] pathParts = path.Split(separator);

			// Find the number of parts in common
			int i;
			for (i = 0; i < rootParts.Length && i < pathParts.Length && rootParts[i] == pathParts[i]; ++i);

			// Build the result 
			if (i == 0)
				return path;

			StringBuilder buffer = new StringBuilder(512);
			for (int j = i; j < rootParts.Length; ++j)
			{
				if (rootParts[j] != string.Empty)
				{
					buffer.Append("..");
					buffer.Append(Path.DirectorySeparatorChar);
				}
			}
			for (int j = i; j < pathParts.Length; ++j)
			{
				buffer.Append(pathParts[j]);
				buffer.Append(Path.DirectorySeparatorChar);
			}

			return buffer.ToString(0, buffer.Length - 1);
		}

		public static string MakeGenericPath(string path)
		{
			return path.Replace(Path.DirectorySeparatorChar, '/');
		}

		public static string MakeNativePath(string path)
		{
			return path.Replace('/', Path.DirectorySeparatorChar);
		}

		//-----------------------------------------------------------------------------

		public static void MountDirectory(string symlink, string path)
		{
			mounts[Path.DirectorySeparatorChar + MakeNativePath(symlink)] = MakeAbsolutePath(path);
		}

		//-----------------------------------------------------------------------------

		public static Stream OpenFile(string path)
		{
			path = MakeNativePath(path);

			// See if this path is part of a mounted filesystem
			if (path[0] == Path.DirectorySeparatorChar)
			{
				foreach (string key in mounts.Keys)
				{
					if (path.StartsWith(key))
						path = mounts[key] + path.Substring(key.Length);
				}
			}

			FileStream fs = new FileStream(path, FileMode.Open);
			return fs;
		}

		//-----------------------------------------------------------------------------

		public static void PushDirectory(string path)
		{
			if (path == null || path.Length == 0)
				path = (string)directoryStack.Peek();
			
			path = MakeNativePath(path);

			// See if this path is part of a mounted filesystem
			if (path[0] == Path.DirectorySeparatorChar)
			{
				foreach (string key in mounts.Keys)
				{
					if (path.StartsWith(key))
						path = mounts[key] + path.Substring(key.Length);
				}
			}
			
			Directory.SetCurrentDirectory(path);
			directoryStack.Push(Directory.GetCurrentDirectory());
		}

		public static void PopDirectory()
		{
			string path = (string)directoryStack.Pop();
			Directory.SetCurrentDirectory((string)directoryStack.Peek());
		}
        public static bool CopyFile(string filename, out string fileNameCopy)
        {
            string[] arrStr = filename.Split(new Char[] { '\\' }, 100);
            string fOld = arrStr[arrStr.GetLength(0) - 1];
            string strPath = string.Empty;
            for (int i = 0; i < arrStr.GetLength(0) - 1; i++)
            {
                strPath += arrStr[i] + "\\";
            }
            fileNameCopy = strPath + "Copy_" + fOld;


            System.IO.File.Copy(filename, fileNameCopy, true);
            return true;

        }
        public static string CopyFile(string filename)
        {
            string fileNameCopy = string.Empty;
            string[] arrStr = filename.Split(new Char[] { '\\' }, 100);
            string fOld = arrStr[arrStr.GetLength(0) - 1];
            string strPath = string.Empty;
            for (int i = 0; i < arrStr.GetLength(0) - 1; i++)
            {
                strPath += arrStr[i] + "\\";
            }
            fileNameCopy = strPath + "Copy_" + fOld;


            System.IO.File.Copy(filename, fileNameCopy, true);
            return fileNameCopy;

        }
		//-----------------------------------------------------------------------------
	}
}
